/*******************************************************************************
 * Copyright (c) 2004, 2007 Mylyn project committers and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/

package org.eclipse.mylyn.rememberthemilk.core;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import org.eclipse.mylyn.rememberthemilk.core.model.RTMInfo.Key;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper;

import com.mdt.rtm.data.RtmTask;

/**
 * Provides a mapping from Mylyn task keys to Trac ticket keys.
 *
 * @author Steffen Pingel
 */
public class RTMAttributeMapper extends TaskAttributeMapper {

	public RTMAttributeMapper(TaskRepository taskRepository) {
		super(taskRepository);
		// TODO Auto-generated constructor stub
	}

	private static final long serialVersionUID = 5333211422546115138L;

	private static Map<String, Attribute> attributeByRTMKey = new HashMap<String, Attribute>();

	private static Map<String, String> rtmKeyByTaskKey = new HashMap<String, String>();

    public static final DateFormat DATE_FORMAT = DateFormat.getDateInstance(2);
    public static final DateFormat TIME_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	public enum Attribute {
		/*CC(Key.CC, "CC:", TaskAttribute.USER_CC, true, false), CHANGE_TIME(Key.CHANGE_TIME,
				"Last Modification:", TaskAttribute.DATE_MODIFIED, true, true), COMPONENT(Key.COMPONENT,
				"Component:", TaskAttribute.PRODUCT), DESCRIPTION(Key.DESCRIPTION, "Description:",
				TaskAttribute.DESCRIPTION, true, false), ID(Key.ID, "<used by search engine>", null, true), KEYWORDS(
				Key.KEYWORDS, "Keywords:", TaskAttribute.KEYWORDS), MILESTONE(Key.MILESTONE, "Milestone:",
				null), NEW_CC(TaskAttribute.NEW_CC, "Add CC:"), OWNER(Key.OWNER, "Assigned to:",
				TaskAttribute.USER_ASSIGNED, true, true), PRIORITY(Key.PRIORITY, "Priority:", null), REPORTER(
				Key.REPORTER, "Reporter:", TaskAttribute.USER_REPORTER, true, true), RESOLUTION(
				Key.RESOLUTION, "Resolution:", TaskAttribute.RESOLUTION, false, true), SEVERITY(Key.SEVERITY,
				"Severity:", null), STATUS(Key.STATUS, "Status:", TaskAttribute.STATUS, false, true), SUMMARY(
				Key.SUMMARY, "Summary:", TaskAttribute.SUMMARY, true), TIME(Key.TIME, "Created:",
				TaskAttribute.DATE_CREATION, true, true), TYPE(Key.TYPE, "Type:", null), VERSION(Key.VERSION,
				"Version:", null);*/

		NAME(Key.NAME, "Name: ", TaskAttribute.SUMMARY, TaskAttribute.TYPE_SHORT_TEXT, true),

		//CC(Key.CC, "CC:", TaskAttribute.USER_CC, true, false),
		//COMPONENT(Key.COMPONENT, "Component:", TaskAttribute.PRODUCT),
		//DESCRIPTION(Key.DESCRIPTION, "Description:", TaskAttribute.DESCRIPTION, true, false),
		ID(Key.ID, "<used by search engine>", null, null, true),
		//KEYWORDS(	Key.KEYWORDS, "Keywords:", TaskAttribute.KEYWORDS),
		//MILESTONE(Key.MILESTONE, "Milestone:",null),
		//NEW_CC(TaskAttribute.NEW_CC, "Add CC:"),
		//OWNER(Key.OWNER, "Assigned to:",TaskAttribute.USER_ASSIGNED, true, true),
		PRIORITY(Key.PRIORITY, "Priority:", TaskAttribute.PRIORITY, TaskAttribute.TYPE_SINGLE_SELECT),
		//REPORTER( Key.REPORTER, "Reporter:", TaskAttribute.USER_REPORTER, true, true),
		//RESOLUTION( Key.RESOLUTION, "Resolution:", TaskAttribute.RESOLUTION, false, true),
		//SEVERITY(Key.SEVERITY,"Severity:", null),
		STATUS(Key.STATUS, "Status:", TaskAttribute.STATUS, TaskAttribute.TYPE_SINGLE_SELECT),
		//SUMMARY(Key.SUMMARY, "Summary:", TaskAttribute.SUMMARY, true),
		//TYPE(Key.TYPE, "Type:", null),
		//VERSION(Key.VERSION,"Version:", null)
		TASKLIST(Key.TASKLIST, "List:", null, TaskAttribute.TYPE_SINGLE_SELECT),
		TASKSERIE(Key.TASKSERIE, "Taskserie:", null, null, false),
		TASKID(Key.TASKID, "TaskId:", null, null, false),
		COMPLETED(Key.COMPLETED, "Completed:", TaskAttribute.DATE_COMPLETION, TaskAttribute.TYPE_DATE, true, true),
		CREATED(Key.CREATED, "Created Date:", TaskAttribute.DATE_CREATION, TaskAttribute.TYPE_DATE, true, true),
		MODIFIED(Key.MODIFIED, "Last Modified:", TaskAttribute.DATE_MODIFICATION, TaskAttribute.TYPE_DATETIME, true, true),
		DUE(Key.DUE, "Due Date:", TaskAttribute.DATE_DUE, TaskAttribute.TYPE_DATE, false, true),
		POSTPONED(Key.POSTPONED, "Postponed:", null, TaskAttribute.TYPE_SHORT_TEXT, false, true),
		TAGS(Key.TAGS, "Tags: ", null, TaskAttribute.TYPE_SHORT_TEXT);

		private final boolean isHidden;

		private final boolean isReadOnly;

		private final String rtmKey;

		private final String prettyName;

		private final String taskKey;

		private final String type;

		Attribute(String tracKey, String prettyName, String taskKey, String type, boolean hidden, boolean readonly) {
			this.rtmKey = tracKey;
			this.taskKey = taskKey;
			this.type = type;
			this.prettyName = prettyName;
			this.isHidden = hidden;
			this.isReadOnly = readonly;

			attributeByRTMKey.put(tracKey, this);
			if (taskKey != null) {
				rtmKeyByTaskKey.put(taskKey, tracKey);
			}
		}

		Attribute(Key key, String prettyName, String taskKey, String type, boolean hidden, boolean readonly) {
			this(key.getKey(), prettyName, taskKey, type, hidden, readonly);
		}

		Attribute(Key key, String prettyName, String taskKey, String type, boolean hidden) {
			this(key.getKey(), prettyName, taskKey, type, hidden, false);
		}

		Attribute(Key key, String prettyName, String taskKey, String type) {
			this(key.getKey(), prettyName, taskKey, type, false, false);
		}

		/**
		 * This is for Mylyn attributes that do not map to Trac attributes.
		 */
		Attribute(String taskKey, String prettyName, String type) {
			this(taskKey, prettyName, taskKey, type, true, false);
		}

		public String getTaskKey() {
			return taskKey;
		}

		public String getRTMKey() {
			return rtmKey;
		}

		public boolean isHidden() {
			return isHidden;
		}

		public boolean isReadOnly() {
			return isReadOnly;
		}

		@Override
		public String toString() {
			return prettyName;
		}

		public String getType() {
			return type;
		}
	}

	static {
		// make sure hash maps get initialized when class is loaded
		Attribute.values();
	}
//
//	@Override
//	public boolean isHidden(String key) {
//		if (isInternalAttribute(key)) {
//			return true;
//		}
//
//		Attribute attribute = attributeByRTMKey.get(key);
//		return (attribute != null) ? attribute.isHidden() : false;
//	}

//	@Override
//	public String getName(String key) {
//		Attribute attribute = attributeByRTMKey.get(key);
//		// TODO if attribute == null it is probably a custom field: need
//		// to query custom field information from repoository
//		return (attribute != null) ? attribute.toString() : key;
//	}
//
//	@Override
//	public boolean isReadOnly(String key) {
//		Attribute attribute = attributeByRTMKey.get(key);
//		return (attribute != null) ? attribute.isReadOnly() : false;
//	}
//
//	@Override
//	public String mapCommonAttributeKey(String key) {
//		String tracKey = rtmKeyByTaskKey.get(key);
//		return (tracKey != null) ? tracKey : key;
//	}
//
//	static boolean isInternalAttribute(String id) {
//		// TODO: look for new stuff which matches remove cc and new cc
//		return TaskAttribute.COMMENT_NEW.equals(id) || /*TaskAttribute.REMOVE_CC.equals(id)
//				|| TaskAttribute.NEW_CC.equals(id) ||*/ TaskAttribute.ADD_SELF_CC.equals(id);
//	}
//
//	@Override
//	public Date getDateForAttributeType(String attributeKey, String dateString) {
//		if (dateString == null || dateString.length() == 0) {
//			return null;
//		}
//
//		try {
//			String mappedKey = mapCommonAttributeKey(attributeKey);
//			if (mappedKey.equals(Attribute.TIME.getRTMKey()) || mappedKey.equals(Attribute.CHANGE_TIME.getRTMKey())) {
//				return new Date(Integer.valueOf(dateString));
//			}
//		} catch (Exception e) {
//		}
//		return null;
//	}

	@Override
	public String mapToRepositoryKey(TaskAttribute parent, String key) {
		for (Attribute attr: Attribute.values()) {
			if (key.equals(attr.getTaskKey())) {
				key = attr.getRTMKey();
				break;
			}
		}
		return key;
	}

	@Override
	public Map<String, String> getOptions(TaskAttribute attribute) {
		Map<String, String> optionsMap = new LinkedHashMap<String, String>();
		if (attribute.getOptions().size() > 0) {
			optionsMap = attribute.getOptions();
		} else if (attribute.getId().equals(Attribute.PRIORITY.getRTMKey())){
			optionsMap.put(ITask.PriorityLevel.P1.toString(), RtmTask.Priority.High.toString());
			optionsMap.put(ITask.PriorityLevel.P2.toString(), RtmTask.Priority.Medium.toString());
			optionsMap.put(ITask.PriorityLevel.P4.toString(), RtmTask.Priority.Low.toString());
			optionsMap.put(ITask.PriorityLevel.P3.toString(), RtmTask.Priority.None.toString());
		} else if (attribute.getId().equals(Attribute.STATUS.getRTMKey())) {
			optionsMap.put("complete", "Complete");
			optionsMap.put("incomplete", "Incomplete");
		}
		return optionsMap;
	}

}
